package cn.icanci.loopstack.extensions.spi;

import java.lang.reflect.Field;
import java.util.Set;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.context.ApplicationContext;

import com.google.common.collect.Sets;

/**
 * @author icanci
 * @since 1.0 Created in 2022/12/26 09:57
 */
public class InjectionSpringBeanProcessor {

    /**
     * Spring 上下文
     */
    private final ApplicationContext context;

    public InjectionSpringBeanProcessor(ApplicationContext context) {
        this.context = context;
    }

    /**
     * 后置注入Bean
     *
     * @param spi spi
     */
    public void injectionSpringBeanProcessor(Object spi) {
        SpringBean annotation = spi.getClass().getAnnotation(SpringBean.class);
        if (annotation == null) {
            return;
        }
        Class<?>[] value = annotation.value();
        Set<Class<?>> classes = Sets.newHashSet(value);
        for (Class<?> clazz : classes) {
            injection(spi, clazz);
        }
    }

    /**
     * 为SPI注入Bean
     *
     * @param spi spi
     * @param clazz clazz
     */
    private void injection(Object spi, Class<?> clazz) {
        try {
            Object bean = context.getBean(clazz);
            // 为spi注入
            Field[] fields = FieldUtils.getAllFields(spi.getClass());
            for (Field field : fields) {
                if (field.getType() != clazz) {
                    continue;
                }

                field.setAccessible(true);

                if (field.get(spi) == null) {
                    field.set(spi, bean);
                }
            }
        } catch (Exception e) {
            throw new InjectionBeanException(e);
        }
    }

}
